package controller; import java.text.DecimalFormat; import javax.swing.JOptionPane; import models.DoublePolynomial; /** * * @author Ghiurutan *Class that performs all the operations in the polynomial. */ public class Operations { private DecimalFormat decimalFormat; private static final double EPSILON = 0.00001; private static final int INFINITY = Integer.MAX_VALUE; private static final int MINUS_INFINITY = Integer.MIN_VALUE; private static final int ITERATIONS = 888; public Operations() { decimalFormat = new DecimalFormat(); } public DoublePolynomial add(DoublePolynomial p1, DoublePolynomial p2) { double[] pol1 = p1.getDoublePolynomial(); double[] pol2 = p2.getDoublePolynomial(); int degP1 = p1.getDegree(); int degP2 = p2.getDegree(); int degSum = (degP1 > degP2) ? degP1 : degP2; double[] sum = new double[degSum + 1]; for (int i = 0; i <= degP1; i++) { sum[i] += pol1[i]; } for (int i = 0; i <= degP2; i++) { sum[i] += pol2[i]; } return new DoublePolynomial(sum); } public DoublePolynomial subtract(DoublePolynomial p1, DoublePolynomial p2) { double[] pol1 = p1.getDoublePolynomial(); double[] pol2 = p2.getDoublePolynomial(); int degP1 = p1.getDegree(); int degP2 = p2.getDegree(); int degDif = (degP1 > degP2) ? degP1 : degP2; double[] dif = new double[degDif + 1]; for (int i = 0; i <= degP1; i++) { dif[i] = pol1[i]; } for (int i = 0; i <= degP2; i++) { dif[i] -= pol2[i]; } return new DoublePolynomial(dif); } public DoublePolynomial multiply(DoublePolynomial p1, DoublePolynomial p2) { double[] pol1 = p1.getDoublePolynomial(); double[] pol2 = p2.getDoublePolynomial(); int degP1 = p1.getDegree(); int degP2 = p2.getDegree(); double[] pol = new double[degP1 + degP2 + 1]; for (int i = 0; i <= degP1; i++) { for (int j = 0; j <= degP2; j++) { pol[i + j] += pol1[i] * pol2[j]; } } return new DoublePolynomial(pol); } public DoublePolynomial[] division(DoublePolynomial p1, DoublePolynomial p2) { int degP1 = p1.getDegree(); int degP2 = p2.getDegree(); if (degP1 < degP2 || degP2 == 0) { JOptionPane.showMessageDialog(null, "Error", "Illegal Polynomials entered", JOptionPane.ERROR_MESSAGE); System.exit(0); } int degQ = degP1 - degP2; int i = degQ, j = degP1; double div; double[] quotient = new double[degQ + 1]; double[] dividend = new double[degP1 + 1]; dividend = ((DoublePolynomial) p1.clone()).getDoublePolynomial(); double[] pol2 = ((DoublePolynomial) p2.clone()).getDoublePolynomial(); do { div = dividend[j--] / pol2[degP2]; double[] auxPol = new double[i + 1]; auxPol[i] = div; quotient[i--] = div; dividend = subtract(new DoublePolynomial(dividend), multiply(new DoublePolynomial(pol2), new DoublePolynomial(auxPol))).getDoublePolynomial(); } while (j >= degP2); DoublePolynomial[] result = new DoublePolynomial[] { new DoublePolynomial(quotient), new DoublePolynomial(dividend) }; return result; } public DoublePolynomial derivation(DoublePolynomial p) { double[] derivate = new double[p.getDegree()]; double[] pol = ((DoublePolynomial) p.clone()).getDoublePolynomial(); for (int i = 0; i < derivate.length; i++) { derivate[i] = pol[i + 1] * (i + 1); } return new DoublePolynomial(derivate); } public DoublePolynomial integration(DoublePolynomial p) { double pol[] = ((DoublePolynomial) p.clone()).getDoublePolynomial(); double[] integration = new double[pol.length + 1]; for (int i = 1; i < integration.length; i++) { integration[i] = pol[i - 1] / i; } return new DoublePolynomial(integration); } public boolean areEqual(DoublePolynomial p1, DoublePolynomial p2) { int degP1 = p1.getDegree(); int degP2 = p2.getDegree(); double[] pol1 = ((DoublePolynomial) p1.clone()).getDoublePolynomial(); double[] pol2 = ((DoublePolynomial) p2.clone()).getDoublePolynomial(); if (degP1 != degP2) { return false; } for (int i = 0; i < pol1.length; i++) { if (pol1[i] != pol2[i]) { return false; } } return true; } public double evaluate(DoublePolynomial p, double x) { double[] pol = ((DoublePolynomial) p.clone()).getDoublePolynomial(); double result = 0; for (int i = 0; i < pol.length; i++) { result += pol[i] * Math.pow(x, i); } return result; } public DoublePolynomial exponentiation(DoublePolynomial p, int n) { if (n == 0) { return new DoublePolynomial(1); } else if (n > 0) { double[] pol = ((DoublePolynomial) p.clone()).getDoublePolynomial(); double[] result = new double[p.getDegree() * n + 1]; System.arraycopy(pol, 0, result, 0, pol.length); while (n > 1) { result = multiply(new DoublePolynomial(result), p).getDoublePolynomial(); n--; } return new DoublePolynomial(result); } else { return division(exponentiation(p, 0), exponentiation(p, -n))[0]; } } // Optional private int[] findInterval(DoublePolynomial p) { int[] interval = new int[2]; int n = 0; interval[0] = (int) (Math.random() * 100); interval[1] = (int) (Math.random() * 100) + interval[0]; while (n < ITERATIONS) { if (evaluate(p, interval[0]) * evaluate(p, interval[1]) <= 0) { return interval; } else { interval[0]--; interval[1]++; n++; } } interval[0] = INFINITY; interval[1] = MINUS_INFINITY; return interval; } // finding root using the Bisection Method. private Double findRootAlgorithm(DoublePolynomial p) { int[] interval = findInterval(p); double a = interval[0]; double b = interval[1]; double m; while (Math.abs(b - a) > EPSILON) { m = (a + b) / 2; if (evaluate(p, m) == 0) { return m; } else { if (evaluate(p, a) * evaluate(p, m) <= 0) { b = m; } else { a = m; } } } m = (a + b) / 2; return m; } public String findRoot(DoublePolynomial p) { double rezult = findRootAlgorithm(p); if (rezult >2000000000 || rezult <-2000000000) { return "Polynomial doesn't have real roots."; } else { return decimalFormat.format(rezult); } } // Graph representation methods public double[] computeYCoordinatesForGraph(DoublePolynomial p, double[] xCoordinates) { double[] yCoordinates = new double[xCoordinates.length]; for (int i = 0; i < xCoordinates.length; i++) { yCoordinates[i] = evaluate(p, xCoordinates[i]); } return yCoordinates; } }